import fs from 'fs';
import path from 'path';
import { Context, Dependency, Module, ModuleType, Plugin, PluginLoadResult } from '../core';
import { getModuleTypeFromExtname, isCssModule } from '../utils';
import { ResolveType } from '../compiler';
import { Ast, CssAst } from '../types';
import { parse } from 'postcss';

const CSS_AT_IMPORT_REGEXP = /url\(['"]?([^'"]+)['"]?\)|['"]?([^'"]+)['"]?/;
const CSS_URL_REGEXP = /url\(['"]?([^'"]+)['"]?\)/;

export class CssPlugin implements Plugin {
  name = 'css';

  load(_context: Context, moduleId: string): PluginLoadResult | undefined {
    const extname = path.extname(moduleId);
    if (extname === '.css') {
      return {
        content: fs.readFileSync(moduleId, 'utf-8'),
        moduleType: getModuleTypeFromExtname(extname),
      };
    }
    return;
  }

  parse(_context: Context, _moduleId: string, moduleType: ModuleType, content: string): Ast | undefined {
    if (isCssModule(moduleType)) {
      return parse(content);
    }
    return;
  }

  analyzeDeps(context: Context, module: Module): Dependency[] | undefined {
    if (isCssModule(module.type!)) {
      const deps: Dependency[] = [];

      (module.ast as CssAst).walk(node => {
        // @import
        if (node.type === 'atrule' && node.name === 'import') {
          const match = CSS_AT_IMPORT_REGEXP.exec(node.params);
          if (!match) return;

          const source = match[1] || match[2];
          deps.push({ source, type: ResolveType.CssAtImport });
        } else if (node.type === 'decl') {
          const match = CSS_URL_REGEXP.exec(node.value);
          if (!match) return;

          const source = match[1];
          deps.push({ source, type: ResolveType.CssUrl });
        }
      });

      return deps;
    }
    return;
  }

  transform(context: Context, module: Module): void {
    if (isCssModule(module.type!)) {
      // TODO:
    }
  }
}
